/*****************************************************************************
* | File        :   EPD_4in2b_V2_test.c
* | Author      :   Waveshare team
* | Function    :   4.2inch e-paper B V2 test demo
* | Info        :
*----------------
* | This version:   V1.0
* | Date        :   2020-11-27
* | Info        :
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to  whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
******************************************************************************/
#include "EPD_4in2b_V2_test.h"
#include "EPD_4in2b_V2.h"
#include "GUI_Paint.h"
#include "Debug.h"
#include <stdlib.h>
#include <rtthread.h>

#if 1
void EPD_4IN2B_V2_test(void)
{
    DEBUG("4.2inch e-Paper B V2 demo\n");
    DEV_Module_Init();
    DEBUG("DEV_Module_Init done!\n");

    EPD_4IN2B_V2_Init();
    DEBUG("EPD_4IN2B_V2_Init done!\n");
    EPD_4IN2B_V2_Clear();
    DEBUG("EPD_4IN2B_V2_Clear done!\n");


#if 0
    //1.Initialize the SD card
    SDCard_Init();

    //2.Create a new image cache named IMAGE_BW and fill it with white
    //Draw black picture
    DEBUG("IMAGE_BW\n");
    Paint_NewImage(IMAGE_BW, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE);
    //3.Read BMP pictures into RAM
    SDCard_ReadBMP("4in2b-b.bmp", 0, 0);

    SDCard_Init();
    //Draw red picture
    DEBUG("IMAGE_BWR\n");
    Paint_NewImage(IMAGE_BWR, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE);
    SDCard_ReadBMP("4in2b-r.bmp", 0, 0);

    //4.Refresh the picture in RAM to e-Paper
    EPD_4IN2B_V2_Display();
    DEV_Delay_ms(2000);
#else
#if 0
    DEBUG("show image for array\r\n");
    //1.Draw black image
    Paint_NewImage(IMAGE_BW, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE);
    Paint_DrawBitMap(gImage_4in2bc_b);

    //2.Draw red image
    Paint_NewImage(IMAGE_BWR, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE);
    Paint_DrawBitMap(gImage_4in2bc_ry);
    
    DEBUG("EPD_4IN2B_V2_Display\r\n");
    //3.Refresh the image in RAM to e-Paper
    EPD_4IN2B_V2_Display();
    DEV_Delay_ms(2000);
#endif
#endif

#if 1
    //1.Create a new image cache named IMAGE_BW and fill it with white
    //Draw black picture
    Paint_NewImage(IMAGE_BW, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE);
    
    Paint_DrawPoint(5, 10, BLACK, DOT_PIXEL_1X1, DOT_STYLE_DFT);
    Paint_DrawPoint(5, 20, BLACK, DOT_PIXEL_2X2, DOT_STYLE_DFT);
    Paint_DrawLine(20, 20, 50, 50, BLACK, LINE_STYLE_SOLID, DOT_PIXEL_1X1);
    Paint_DrawLine(50, 20, 20, 50, BLACK, LINE_STYLE_SOLID, DOT_PIXEL_1X1);
    Paint_DrawRectangle(60, 20, 90, 50, BLACK, DRAW_FILL_FULL, DOT_PIXEL_1X1);
    Paint_DrawCircle(35, 90, 15, BLACK, DRAW_FILL_EMPTY, DOT_PIXEL_1X1);
    Paint_DrawString_EN(5, 120, "hello world", &Font12, WHITE, BLACK);
    Paint_DrawNum(5, 140, 123456789, &Font12, BLACK, WHITE);
    // EPD_4IN2B_V2_SetBlack();

    //Draw yellow picture
    Paint_NewImage(IMAGE_BWR, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE);
    
    Paint_DrawPoint(5, 30, RED, DOT_PIXEL_3X3, DOT_STYLE_DFT);
    Paint_DrawPoint(5, 40, RED, DOT_PIXEL_4X4, DOT_STYLE_DFT);
    Paint_DrawLine(35, 75, 35, 105, RED, LINE_STYLE_DOTTED, DOT_PIXEL_1X1);
    Paint_DrawLine(20, 90, 50, 90, RED, LINE_STYLE_DOTTED, DOT_PIXEL_1X1);
    Paint_DrawRectangle(20, 20, 50, 50, RED, DRAW_FILL_EMPTY, DOT_PIXEL_1X1);
    Paint_DrawCircle(75, 90, 15, RED, DRAW_FILL_FULL, DOT_PIXEL_1X1);
    Paint_DrawString_EN(5, 160, "waveshare", &Font16, RED, WHITE);
    Paint_DrawNum(5, 180, 987654321, &Font16, WHITE, RED);
    // EPD_4IN2B_V2_SetRed();

    //show
    DEBUG("EPD_4IN2B_V2_Display...\n");
    EPD_4IN2B_V2_Display();
    DEBUG("EPD_4IN2B_V2_Display done!\n");
    DEV_Delay_ms(1000);
#endif
    DEV_Delay_ms(1000);
    EPD_4IN2B_V2_Clear();
    EPD_4IN2B_V2_Display();

//    EPD_4IN2B_V2_Sleep();
//    DEV_Module_Exit();
}

static int epd_test(int argc, char* argv[])
{
    EPD_4IN2B_V2_test();
    return 0;
}
MSH_CMD_EXPORT(epd_test, e-Paper test);

static int epd_pin_test(int argc, char* argv[])
{
    if (argc <= 1) {
        rt_kprintf("Usage: %s state!\n", __func__);
        rt_kprintf("   state -- 0: Low, 1: High\n", __func__);
        return -1;
    }
    int state = atoi(argv[1]);
    Debug("set all e-paper output pin to %d!\n", state);

    if (state) {
        EPD_CS_1;
        EPD_DC_1;
        EPD_RST_1;
        SPIRAM_CS_1;
    } else {
        EPD_CS_0;
        EPD_DC_0;
        EPD_RST_0;
        SPIRAM_CS_0;
    }

    return 0;
}
MSH_CMD_EXPORT(epd_pin_test, e-Paper pin test);

enum ColorType colorTypes[] = {
        COLOR_WHITE,
        COLOR_BLACK,
        COLOR_RED};

void EPD_Draw_chess_board(UWORD size, enum ColorType firstColor)
{
    EPD_4IN2B_V2_Init();
    EPD_4IN2B_V2_Clear();
    DEBUG("Draw BLACK/WHITE rectangles\n");
    Paint_NewImage(IMAGE_BW, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE);

    UWORD SIZE = (size % 2 == 0) ? size : (size / 2 * 2);
    UWORD ROWS = EPD_4IN2B_V2_HEIGHT / SIZE;
    UWORD COLS = EPD_4IN2B_V2_WIDTH / SIZE;
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            enum ColorType colorId = colorTypes[(i * COLS + j + firstColor) % COLOR_NUMS];
//            printf("(%d, %d), colorId = 0x%X\n", i, j, colorId);
            if (colorId != COLOR_RED) {
                UWORD color = colorId == COLOR_BLACK ? BLACK : WHITE;
                UWORD x_start = j * SIZE;
                UWORD y_start = i * SIZE;
                UWORD x_end = x_start + SIZE;
                UWORD y_end = y_start + SIZE;
                Paint_DrawRectangle(x_start, y_start, x_end, y_end, color, DRAW_FILL_FULL, DOT_PIXEL_1X1);
            }
        }
    }

    DEBUG("Draw RED rectangles\n");
    Paint_NewImage(IMAGE_BWR, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE);
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            enum ColorType colorId = colorTypes[(i * COLS + j + firstColor) % COLOR_NUMS];
//            printf("(%d, %d), colorId = 0x%X\n", i, j, colorId);
            if (colorId == COLOR_RED) {
                UWORD color = RED;
                UWORD x_start = j * SIZE;
                UWORD y_start = i * SIZE;
                UWORD x_end = x_start + SIZE;
                UWORD y_end = y_start + SIZE;
                Paint_DrawRectangle(x_start, y_start, x_end, y_end, color, DRAW_FILL_FULL, DOT_PIXEL_1X1);
            }
        }
    }
    DEBUG("Display rectangles\n");
    EPD_4IN2B_V2_Display();
}

static int epd_draw_box(int argc, char* argv[])
{
    if (argc <= 1) {
        rt_kprintf("Usage: %s size first_color\n", __func__);
        rt_kprintf("       size  -- width and height of each square\n");
        rt_kprintf(" first_color -- first square color, 0: White, 1: Black, 2: Red\n");
        return -1;
    }
    UWORD size = atoi(argv[1]);
    uint8_t color = atoi(argv[2]) % COLOR_NUMS;
    rt_kprintf("size = %d, color = %d\n", size, color);
    EPD_Draw_chess_board(size, color);
    return 0;
}
MSH_CMD_EXPORT(epd_draw_box, e-Paper draw chess board test);

static void EPD_Full_fill(enum ColorType colorId)
{
    UWORD color;
    EPD_4IN2B_V2_Init();
    EPD_4IN2B_V2_Clear();

    DEBUG("Update frame buffer BLACK/WHITE memory!\n");
    Paint_NewImage(IMAGE_BW, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE); // clear Black/White memory
    if (colorId != COLOR_RED) {
        UWORD color = colorId == COLOR_BLACK ? BLACK : WHITE;
        Paint_DrawRectangle(0, 0, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, color, DRAW_FILL_FULL, DOT_PIXEL_1X1);
    }

    DEBUG("Update frame buffer RED memory!\n");
    Paint_NewImage(IMAGE_BWR, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_Clear(WHITE); // clear Red memory

    if (colorId == COLOR_RED) {
        color = RED; // (colorType == COLOR_RED) ? BLACK : WHITE;
        Paint_DrawRectangle(0, 0, EPD_4IN2B_V2_WIDTH, EPD_4IN2B_V2_HEIGHT, color, DRAW_FILL_FULL, DOT_PIXEL_1X1);
    }

    DEBUG("Display frame buffer!\n");
    EPD_4IN2B_V2_Display();
}

static int epd_fill(int argc, char* argv[])
{
    if (argc <= 1) {
        rt_kprintf("Usage: %s color\n", __func__);
        rt_kprintf("       color -- fill color, 0: White, 1: Black, 2: Red\n");
        return -1;
    }

    enum ColorType colorId = colorTypes[atoi(argv[1]) % COLOR_NUMS];
    rt_kprintf("full fill screen with %d\n", colorId);
    EPD_Full_fill(colorId);
    rt_kprintf("%s done!\n", __func__);
    return 0;
}
MSH_CMD_EXPORT(epd_fill, e-Paper full fill with color);
#endif



